package com.hsogoo.avatar.transport.netty;

import java.util.List;

import com.hsogoo.avatar.model.AvatarRequest;
import com.hsogoo.avatar.model.AvatarResponse;
import com.hsogoo.avatar.serialization.Serializer;
import com.hsogoo.avatar.serialization.SerializerFactory;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

/**
 * Created by za-huangsaigang on 2018/10/15.
 */
public class ProtocolDecoder extends ByteToMessageDecoder {

    //判断传送客户端传送过来的数据是否按照协议传输，头部信息的大小应该是 byte+byte+int = 1+1+4 = 6
    private static final int HEADER_SIZE = 6;

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        if (in.readableBytes() < HEADER_SIZE) {
            return;
        }
        in.markReaderIndex();                   //我们标记一下当前的readIndex的位置
        byte flag = in.readByte();              //获取flag判断是request还是response
        byte serializerCode = in.readByte();    //获取序列化标记
        int dataLength = in.readInt();          // 读取传送过来的消息的长度。ByteBuf 的readInt()方法会让他的readIndex增加4
        if (dataLength < 0) {                   // 我们读到的消息体长度为0，这是不应该出现的情况，这里出现这情况，关闭连接。
            ctx.close();
        }

        if (in.readableBytes() < dataLength) {  //读到的消息体长度如果小于我们传送过来的消息长度，则resetReaderIndex.
                                                // 这个配合markReaderIndex使用的。把readIndex重置到mark的地方
            in.resetReaderIndex();
            return;
        }

        byte[] body = new byte[dataLength];
        in.readBytes(body);
        Serializer serializer = serializerCode == 0 ? SerializerFactory.getSerializer() : SerializerFactory.getSerializer(serializerCode);
        Class clazz = null;
        if(flag == 0X01){
            clazz = AvatarRequest.class;
        }else if(flag == 0X02){
            clazz = AvatarResponse.class;
        }
        Object o = serializer.decode(body, clazz);
        out.add(o);
    }
}
